import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { EnterpriseModule } from './modules/enterprise/enterprise.module';
import { GlobalMiddleware } from './common/middleware/global.middleware';
import { ConfigModule, ConfigService } from '@nestjs/config';
import configuration from './config/index';
import { TypeOrmModule, TypeOrmModuleOptions } from '@nestjs/typeorm';
import { UserModule } from './modules/user/user.module';
import { DriverModule } from './modules/driver/driver.module';
import { WaybillModule } from './modules/waybill/waybill.module';
import { AuthModule } from './modules/auth/auth.module';
import { MainModule } from './modules/main/main.module';
import { JwtAuthGuard } from './common/guards/auth.guard';
import { APP_GUARD } from '@nestjs/core';
import { RoleGuard } from './common/guards/role.guard';
import { RoleModule } from './modules/role/role.module';
import { PermModule } from './modules/perm/perm.module';
import { CommonModule } from './modules/common/common.module';
import { CaptchaModule } from './modules/captcha/captcha.module';
import { UploadModule } from './modules/upload/upload.module';
import { ServeStaticModule } from '@nestjs/serve-static';
import * as path from 'path';
import { AuditSubscriber } from './common/subscribers';
import { MenuModule } from './modules/menu/menu.module';
import { CarbillModule } from './modules/carbill/carbill.module';
import { MapModule } from './modules/map/map.module';
import { PageModule } from './modules/page/page.module';
import { ClientModule } from './modules/client/client.module';
import { BranchModule } from './modules/branch/branch.module';

@Module({
  imports: [
    ConfigModule.forRoot({
      cache: true,
      load: [configuration],
      isGlobal: true,
    }),
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (config: ConfigService) =>
        ({
          type: 'mysql',
          entities: [`${__dirname}/**/*.entity{.ts,.js}`],
          keepConnectionAlive: true,
          autoLoadEntities: true,
          timezone: '+08:00',
          subscribers: [AuditSubscriber],
          ...(config.get('db.mysql') as object),
        }) as TypeOrmModuleOptions,
    }),
    EnterpriseModule,
    UserModule,
    DriverModule,
    WaybillModule,
    AuthModule,
    MainModule,
    RoleModule,
    PermModule,
    CommonModule,
    CaptchaModule,
    UploadModule,
    ServeStaticModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (config) => [
        {
          rootPath: path.join(process.cwd(), config.get('app.file.location')),
          serveRoot: config.get('app.file.serveRoot'),
        },
      ],
      inject: [ConfigService],
    }),
    MenuModule,
    CarbillModule,
    MapModule,
    PageModule,
    ClientModule,
    BranchModule,
  ],
  controllers: [],
  providers: [
    {
      provide: APP_GUARD,
      useClass: JwtAuthGuard,
    },
    {
      provide: APP_GUARD,
      useClass: RoleGuard,
    },
  ],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(GlobalMiddleware).forRoutes('*');
  }
}
